package com.py.framework.service.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Model;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.py.framework.common.TaskHelper;
import com.py.framework.core.common.Page;
import com.py.framework.core.exception.ServiceException;
import com.py.framework.core.log.ExceptionLogger;
import com.py.framework.service.ActManageService;
import com.py.framework.service.WorkFlowService;

/**
 * 工作流管理Service实现
 * 
 * @author Leegern
 * @date 2018年5月22日
 */
@Service
public class ActManageServiceImpl implements ActManageService {

	/** 注入工作流相关实例 **/
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private WorkFlowService workflowService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.py.framework.service.ActManageService#queryActDataList(com.py.
	 * framework.core.common.Page, java.lang.String)
	 */
	@Override
	public List<Model> queryActDataList(Page page, String actName) {
		List<Model> datas = null;
		int startIndex = (page.getCurrentPage() - 1) * page.getPageSize();
		long count = 0;
		if (StringUtils.isNotBlank(actName)) {
			count = repositoryService.createModelQuery().modelNameLike(actName).count();
			datas = repositoryService.createModelQuery().modelNameLike(actName).listPage(startIndex,
					page.getPageSize());
		} else {
			count = repositoryService.createModelQuery().count();
			datas = repositoryService.createModelQuery().orderByCreateTime().desc().listPage(startIndex,
					page.getPageSize());
		}
		page.setTotalCount((int) count);
		return datas;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.py.framework.service.ActManageService#createAct(java.lang.String,
	 * java.lang.String, java.lang.String)
	 */
	@Override
	public String createAct(String actName, String actKey, String actDesc) {
		ObjectMapper objectMapper = new ObjectMapper();
		ObjectNode editorNode = objectMapper.createObjectNode();
		editorNode.put("id", "canvas");
		editorNode.put("resourceId", "canvas");
		ObjectNode stencilSetNode = objectMapper.createObjectNode();
		stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
		// editorNode.put("stencilset", stencilSetNode);
		editorNode.set("stencilset", stencilSetNode);
		Model modelData = repositoryService.newModel();

		ObjectNode modelObjectNode = objectMapper.createObjectNode();
		modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, actName);
		modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);

		actDesc = StringUtils.defaultString(actDesc);
		modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, actDesc);
		modelData.setMetaInfo(modelObjectNode.toString());
		modelData.setName(actName);
		modelData.setKey(StringUtils.defaultString(actKey));

		try {
			repositoryService.saveModel(modelData);
			repositoryService.addModelEditorSource(modelData.getId(),
					editorNode.toString().getBytes(TaskHelper.CHARSET_UTF_8));
		} catch (UnsupportedEncodingException e) {
			ExceptionLogger.error(e);
			throw new ServiceException("create atciviti model error[actName=" + actName + "].");
		}
		return modelData.getId();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.py.framework.service.ActManageService#deployAct(java.lang.String)
	 */
	@Override
	public int deployAct(String modelId) {
		if (StringUtils.isNotBlank(modelId)) {
			try {
				// 读取model文件
				Model modelData = repositoryService.getModel(modelId);
				ObjectNode modelNode = (ObjectNode) new ObjectMapper()
						.readTree(repositoryService.getModelEditorSource(modelData.getId()));
				byte[] bpmnBytes = null;
				BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
				bpmnBytes = new BpmnXMLConverter().convertToXML(model);
				String processName = modelData.getName() + ".bpmn20.xml";
				repositoryService.createDeployment().name(modelData.getName())
						.addString(processName, new String(bpmnBytes, "UTF-8")).deploy(); // 部署中文乱码fix
			} catch (IOException e) {
				ExceptionLogger.error(e);
				throw new ServiceException("deploy atciviti model error[modelId=" + modelId + "].");
			}
		}
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.py.framework.service.ActManageService#deleteAct(java.util.List)
	 */
	@Override
	public int deleteAct(List<String> modelIds) {
		int count = 0;
		if (!CollectionUtils.isEmpty(modelIds)) {
			for (String modelId : modelIds) {
				if (StringUtils.isNotBlank(modelId)) {
					repositoryService.deleteModel(modelId);
					count++;
				}
			}
		}
		return count;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.py.framework.service.ActManageService#getActsByName(java.lang.String)
	 */
	@Override
	public int getActsByName(String actName) {
		if (StringUtils.isNotBlank(actName)) {
			return workflowService.getActsByName(actName);
		}
		return 0;
	}
}